<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Inferences</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script>
function togglePopup(material_id) {
  var popup = document.getElementById(material_id);
  popup.classList.toggle("show");
}
</script>

<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
<script src="http://code.jquery.com/jquery-1.12.4.min.js"
	integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>

<script src="../docs-assets/Bigfoot.js"></script>
<link href="../docs-assets/Bigfoot.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Inferences' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../inform7n.html">Inform7</a></li><li><a href="index.html">knowledge</a></li><li><a href="index.html#5">Chapter 5: Modelling</a></li><li><b>Inferences</b></li></ul></div>
<p class="purpose">An inference is a single datum about the world model, believed to be true or untrue and with some degree of certainty.</p>

<ul class="toc"><li><a href="5-inf.html#SP1">&#167;1. Inferences</a></li><li><a href="5-inf.html#SP3">&#167;3. Access functions</a></li><li><a href="5-inf.html#SP5">&#167;5. Looping over inferences</a></li><li><a href="5-inf.html#SP6">&#167;6. Comparing inferences</a></li><li><a href="5-inf.html#SP8">&#167;8. Joining an inference to a subject</a></li><li><a href="5-inf.html#SP9">&#167;9. Logging inferences</a></li><li><a href="5-inf.html#SP10">&#167;10. Inference families</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. Inferences.</b>This is quite a lightweight structure:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">inference</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">inference_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">family</span><span class="plain-syntax">; </span><span class="comment-syntax"> see above</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">general_pointer</span><span class="plain-syntax"> </span><span class="identifier-syntax">data</span><span class="plain-syntax">; </span><span class="comment-syntax"> details specific to the family</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">certainty</span><span class="plain-syntax">; </span><span class="comment-syntax"> any </span><span class="extract"><span class="extract-syntax">*_CE</span></span><span class="comment-syntax"> value other than </span><span class="extract"><span class="extract-syntax">UNKNOWN_CE</span></span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inferred_from</span><span class="plain-syntax">; </span><span class="comment-syntax"> from what sentence was this drawn?</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">drawn_during_stage</span><span class="plain-syntax">; </span><span class="comment-syntax"> or was this drawn during the model completion stage?</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">drawn_from_metadata</span><span class="plain-syntax">; </span><span class="comment-syntax"> or from the project's metadata file?</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">inference</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>The structure inference is accessed in 1/ap, 2/iaa, 3/epa, 5/pi, 5/ri and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. </b>The following routine coins a newly minted inference which is not yet attached
to any subject: but it will not stay unattached for long. Note that if nothing
has been said about likelihood, it is assumed to be factually certain.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="function-syntax">Inferences::create_inference</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Inferences::create_inference</span></span>:<br/>Property Inferences - <a href="5-pi.html#SP3">&#167;3</a><br/>Relation Inferences - <a href="5-ri.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</span><span class="plain-syntax">, </span><span class="identifier-syntax">general_pointer</span><span class="plain-syntax"> </span><span class="identifier-syntax">data</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">certitude</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="constant-syntax">PROTECTED_MODEL_PROCEDURE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">f</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"inference orphaned"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">certitude</span><span class="plain-syntax"> == </span><span class="identifier-syntax">UNKNOWN_CE</span><span class="plain-syntax">) </span><span class="identifier-syntax">certitude</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">new_i</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">inference</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">new_i</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family</span><span class="plain-syntax"> = </span><span class="identifier-syntax">f</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">new_i</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">data</span><span class="plain-syntax"> = </span><span class="identifier-syntax">data</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">new_i</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">certainty</span><span class="plain-syntax"> = </span><span class="identifier-syntax">certitude</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">new_i</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inferred_from</span><span class="plain-syntax"> = </span><span class="identifier-syntax">current_sentence</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">new_i</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">drawn_during_stage</span><span class="plain-syntax"> = </span><a href="5-tmw.html#SP1" class="function-link"><span class="function-syntax">World::current_building_stage</span></a><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">new_i</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">drawn_from_metadata</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">new_i</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. Access functions.</b>Once drawn, inferences are mostly read-only, but the following access routines
allow them to be read.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">inference_family</span><span class="plain-syntax"> *</span><span class="function-syntax">Inferences::get_inference_type</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Inferences::get_inference_type</span></span>:<br/>Properties - <a href="3-prp.html#SP21">&#167;21</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="function-syntax">Inferences::where_inferred</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Inferences::where_inferred</span></span>:<br/>Properties - <a href="3-prp.html#SP21">&#167;21</a><br/>Variable Subjects - <a href="4-vs.html#SP2">&#167;2</a><br/>Relation Subjects - <a href="4-rs.html#SP4">&#167;4</a><br/>Property Inferences - <a href="5-pi.html#SP11">&#167;11</a>, <a href="5-pi.html#SP15">&#167;15</a><br/>Indefinite Appearance - <a href="5-ia.html#SP1_1">&#167;1.1</a>, <a href="5-ia.html#SP2">&#167;2</a><br/>The Model World - <a href="5-tmw.html#SP4_2_1_1_1">&#167;4.2.1.1.1</a>, <a href="5-tmw.html#SP4_3">&#167;4.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inferred_from</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Inferences::get_certainty</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Inferences::get_certainty</span></span>:<br/>Properties - <a href="3-prp.html#SP21">&#167;21</a><br/>Relation Subjects - <a href="4-rs.html#SP4">&#167;4</a><br/>Property Inferences - <a href="5-pi.html#SP10">&#167;10</a>, <a href="5-pi.html#SP11">&#167;11</a><br/>The Model World - <a href="5-tmw.html#SP4_2">&#167;4.2</a>, <a href="5-tmw.html#SP4_2_1_1">&#167;4.2.1.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">certainty</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Inferences::during_stage</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Inferences::during_stage</span></span>:<br/>The Model World - <a href="5-tmw.html#SP4_2">&#167;4.2</a>, <a href="5-tmw.html#SP4_2_1">&#167;4.2.1</a><br/>The Naming Thicket - <a href="5-tnt.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">drawn_during_stage</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. </b>This is very occasionally used in world modelling, when it has become
clear that an inference can be ignored.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Inferences::render_impossible</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Inferences::render_impossible</span></span>:<br/>The Model World - <a href="5-tmw.html#SP4_2_1_1">&#167;4.2.1.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">i</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">i</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">certainty</span><span class="plain-syntax"> = </span><span class="identifier-syntax">IMPOSSIBLE_CE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. Looping over inferences.</b>The following macro prototypes show how to loop through all of the inferences
known concerning a given inference subject, and of a given type. "Positive"
knowledge means that the inferences must be more likely to be true than false.
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="identifier-syntax">POSITIVE_KNOWLEDGE_LOOP</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">type</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">infs</span><span class="plain-syntax">)?(</span><a href="4-is.html#SP13" class="function-link"><span class="function-syntax">InferenceSubjects::get_inferences</span></a><span class="plain-syntax">(</span><a href="4-is.html#SP9" class="function-link"><span class="function-syntax">InferenceSubjects::divert</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">))):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">inf</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family</span><span class="plain-syntax"> == </span><span class="identifier-syntax">type</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">inf</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">certainty</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">))</span>
<span class="definition-keyword">define</span> <span class="identifier-syntax">KNOWLEDGE_LOOP</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">type</span><span class="plain-syntax">)</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        (</span><span class="identifier-syntax">infs</span><span class="plain-syntax">)?(</span><a href="4-is.html#SP13" class="function-link"><span class="function-syntax">InferenceSubjects::get_inferences</span></a><span class="plain-syntax">(</span><a href="4-is.html#SP9" class="function-link"><span class="function-syntax">InferenceSubjects::divert</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">))):</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">inf</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family</span><span class="plain-syntax"> == </span><span class="identifier-syntax">type</span><span class="plain-syntax">)</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. Comparing inferences.</b>The following function is a little like <span class="extract"><span class="extract-syntax">strcmp</span></span>, the standard C routine
for comparing strings. It compares two inferences <span class="extract"><span class="extract-syntax">i1</span></span> and <span class="extract"><span class="extract-syntax">i2</span></span> and returns
a value useful for sorting algorithms: 0 if equal, positive if <span class="extract"><span class="extract-syntax">i1 &lt; i2</span></span>,
negative if <span class="extract"><span class="extract-syntax">i2 &lt; i1</span></span>. This is a stable trichotomy; in particular,
<span class="extract"><span class="extract-syntax">Inferences::cmp(i1, i2) == -Inferences::cmp(i2, i1)</span></span>.
</p>

<p class="commentary">With most sorting functions only the sign of the return value is significant,
but here the magnitude matters as well. It will always be one of the following.
</p>

<p class="commentary">"Topic" here means the basic fact being asserted. For example, an inference
that north from X is Y differs in topic from an inference that east from X is Z.
"Content" means what that fact is saying. For example, an inference that north
from X is Y differs in content from an inference that north from X is Z.
</p>

<p class="commentary">Inferences differ in Boolean content if the content in question can only have
two values. For example, an inference that a jar is open differs in Boolean
content from an inference that it is closed.
</p>

<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">CI_DIFFER_IN_EXISTENCE</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax"> </span><span class="comment-syntax"> one exists, the other doesn't</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">CI_DIFFER_IN_FAMILY</span><span class="plain-syntax"> </span><span class="constant-syntax">2</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">CI_DIFFER_IN_TOPIC</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">CI_DIFFER_IN_BOOLEAN_CONTENT</span><span class="plain-syntax"> </span><span class="constant-syntax">4</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">CI_DIFFER_IN_CONTENT</span><span class="plain-syntax"> </span><span class="constant-syntax">5</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">CI_DIFFER_IN_COPY_ONLY</span><span class="plain-syntax"> </span><span class="constant-syntax">6</span><span class="plain-syntax"> </span><span class="comment-syntax"> these are different but duplicate inferences</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">CI_IDENTICAL</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax"> </span><span class="comment-syntax"> these are pointers to the same inference in memory</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Inferences::cmp</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">Inferences::cmp</span></span>:<br/><a href="5-inf.html#SP8">&#167;8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">i1</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">i2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">i2</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">CI_IDENTICAL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i1</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">CI_DIFFER_IN_EXISTENCE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i2</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -</span><span class="constant-syntax">CI_DIFFER_IN_EXISTENCE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><a href="5-inf.html#SP7" class="function-link"><span class="function-syntax">Inferences::measure_family</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family</span><span class="plain-syntax">) -</span>
<span class="plain-syntax">            </span><a href="5-inf.html#SP7" class="function-link"><span class="function-syntax">Inferences::measure_family</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i2</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">CI_DIFFER_IN_FAMILY</span><span class="plain-syntax">; </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -</span><span class="constant-syntax">CI_DIFFER_IN_FAMILY</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><a href="5-inf.html#SP12" class="function-link"><span class="function-syntax">Inferences::family_specific_cmp</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i1</span><span class="plain-syntax">, </span><span class="identifier-syntax">i2</span><span class="plain-syntax">); </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><a href="5-inf.html#SP7" class="function-link"><span class="function-syntax">Inferences::measure_inf</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i1</span><span class="plain-syntax">) - </span><a href="5-inf.html#SP7" class="function-link"><span class="function-syntax">Inferences::measure_inf</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">i2</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">CI_DIFFER_IN_COPY_ONLY</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> -</span><span class="constant-syntax">CI_DIFFER_IN_COPY_ONLY</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">CI_IDENTICAL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. </b>Funny story: until 2019, inference comparison ran by using pointer
subtraction when comparing, say, subject references, on the principle that the
ordering doesn't really matter so long as it is definite and stable during a
run. But in the late 2010s, desktop operating systems such as MacOS Mojave
began to randomize the address space of all executables, to make it harder for
attackers to exploit buffer overflow bugs. As a result, although <a href="5-inf.html#SP6" class="internal">Inferences::cmp</a>
continued to make definite orderings, they would be randomly different from
one run to another. Inform's output remained functionally correct, but the
generated I6 code would subtly differ from run to run. And so we instead now
incur the cost of looking up allocation IDs. Those count from 0, so we add 1
to differentiate them from the null pointer, which scores 0.
</p>

<p class="commentary">Pointer subtraction is, in any case, frowned on in all the best houses, so this
was probably a good thing.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Inferences::measure_family</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">Inferences::measure_family</span></span>:<br/><a href="5-inf.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">F</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax"> + </span><span class="identifier-syntax">F</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Inferences::measure_property</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Inferences::measure_property</span></span>:<br/>Property Inferences - <a href="5-pi.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">property</span><span class="plain-syntax"> *</span><span class="identifier-syntax">P</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">P</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax"> + </span><span class="identifier-syntax">P</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Inferences::measure_inf</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Inferences::measure_inf</span></span>:<br/><a href="5-inf.html#SP6">&#167;6</a><br/>Property Inferences - <a href="5-pi.html#SP6">&#167;6</a><br/>Relation Inferences - <a href="5-ri.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">I</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">I</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax"> + </span><span class="identifier-syntax">I</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Inferences::measure_infs</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Inferences::measure_infs</span></span>:<br/>Relation Inferences - <a href="5-ri.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">IS</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">IS</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax"> + </span><span class="identifier-syntax">IS</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Inferences::measure_pn</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Inferences::measure_pn</span></span>:<br/>Relation Inferences - <a href="5-ri.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">parse_node</span><span class="plain-syntax"> *</span><span class="identifier-syntax">N</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">N</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span><span class="plain-syntax"> + </span><span class="identifier-syntax">N</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">allocation_id</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. Joining an inference to a subject.</b>Each inference subject has a list of inferences concerning it. The process
of adding a new one is called "joining".
</p>

<p class="commentary">If we simply added it blindly to the end of the list, we might heap up all
kinds of contradictions or redundancies, so we use the above comparison
function to keep a tidy list in which neither can appear. The following code
looks simple enough, but took a long time to get right.
</p>

<p class="commentary">The loop here completes if and only if the inference is safely joined to the
list; that is, if it is found to contradict or duplicate existing knowledge,
then the function exits without completing the loop.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Inferences::join_inference</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">Inferences::join_inference</span></span>:<br/>Property Inferences - <a href="5-pi.html#SP4">&#167;4</a><br/>Relation Inferences - <a href="5-ri.html#SP4">&#167;4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="constant-syntax">PROTECTED_MODEL_PROCEDURE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">inf</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"joining null inference"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">infs</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"joining to null inference subject"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">infs</span><span class="plain-syntax"> = </span><a href="4-is.html#SP9" class="function-link"><span class="function-syntax">InferenceSubjects::divert</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">SL</span><span class="plain-syntax"> = </span><a href="4-is.html#SP13" class="function-link"><span class="function-syntax">InferenceSubjects::get_inferences</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">existing</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">insertion_point</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">existing</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference</span><span class="plain-syntax">, </span><span class="identifier-syntax">SL</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><a href="5-inf.html#SP6" class="function-link"><span class="function-syntax">Inferences::cmp</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">existing</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="constant-syntax">CI_IDENTICAL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"inference joined twice"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">level_of_disagreement</span><span class="plain-syntax"> = </span><span class="identifier-syntax">abs</span><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">level_of_disagreement</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">CI_DIFFER_IN_TOPIC</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="named-paragraph-container code-font"><a href="5-inf.html#SP8_2" class="named-paragraph-link"><span class="named-paragraph">These relate to the same basic fact and one must exclude the other</span><span class="named-paragraph-number">8.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="5-inf.html#SP8_1" class="named-paragraph-link"><span class="named-paragraph">Insert the newly-drawn inference here</span><span class="named-paragraph-number">8.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">insertion_point</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="named-paragraph-container code-font"><a href="5-inf.html#SP8_1" class="named-paragraph-link"><span class="named-paragraph">Insert the newly-drawn inference here</span><span class="named-paragraph-number">8.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8_1" class="paragraph-anchor"></a><b>&#167;8.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Insert the newly-drawn inference here</span><span class="named-paragraph-number">8.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">LinkedLists::insert</span><span class="plain-syntax">(</span><span class="identifier-syntax">SL</span><span class="plain-syntax">, </span><span class="identifier-syntax">insertion_point</span><span class="plain-syntax">, </span><span class="identifier-syntax">inf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="5-inf.html#SP9" class="function-link"><span class="function-syntax">Inferences::report_inference</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="string-syntax">"drawn"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">PluginCalls::inference_drawn</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-inf.html#SP8">&#167;8</a> (twice).</li></ul>
<p class="commentary firstcommentary"><a id="SP8_2" class="paragraph-anchor"></a><b>&#167;8.2. </b>For example, we would be here if <span class="extract"><span class="extract-syntax">inf</span></span> said that the carrying capacity of
the Canopus jar was 10, and <span class="extract"><span class="extract-syntax">existing</span></span> said it was 12: these inferences concern
the same basic fact, i.e., what the carrying capacity of the jar is.
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">These relate to the same basic fact and one must exclude the other</span><span class="named-paragraph-number">8.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">inf_sureness</span><span class="plain-syntax"> = </span><span class="identifier-syntax">abs</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">certainty</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">existing_sureness</span><span class="plain-syntax"> = </span><span class="identifier-syntax">abs</span><span class="plain-syntax">(</span><span class="identifier-syntax">existing</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">certainty</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">existing_sureness</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">inf_sureness</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><a href="5-inf.html#SP9" class="function-link"><span class="function-syntax">Inferences::report_inference</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="string-syntax">"discarded (we already know better)"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">existing_sureness</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">inf_sureness</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LinkedLists::set_entry</span><span class="plain-syntax">(</span><span class="identifier-syntax">insertion_point</span><span class="plain-syntax">, </span><span class="identifier-syntax">SL</span><span class="plain-syntax">, </span><span class="identifier-syntax">inf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><a href="5-inf.html#SP9" class="function-link"><span class="function-syntax">Inferences::report_inference</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="string-syntax">"replaced existing less certain one"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">PluginCalls::inference_drawn</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">contradiction_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="named-paragraph-container code-font"><a href="5-inf.html#SP8_2_1" class="named-paragraph-link"><span class="named-paragraph">Determine whether or not they contradict each other</span><span class="named-paragraph-number">8.2.1</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">contradiction_flag</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">inf_sureness</span><span class="plain-syntax"> == </span><span class="identifier-syntax">CERTAIN_CE</span><span class="plain-syntax">)</span>
<span class="plain-syntax">                </span><span class="named-paragraph-container code-font"><a href="5-inf.html#SP8_2_2" class="named-paragraph-link"><span class="named-paragraph">Contradictions of certainty are forbidden, so issue a problem</span><span class="named-paragraph-number">8.2.2</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">inf_sureness</span><span class="plain-syntax"> == </span><span class="identifier-syntax">LIKELY_CE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax">                (</span><a href="4-is.html#SP20" class="function-link"><span class="function-syntax">InferenceSubjects::get_default_certainty</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">infs</span><span class="plain-syntax">) == </span><span class="identifier-syntax">LIKELY_CE</span><span class="plain-syntax">))</span>
<span class="plain-syntax">                </span><span class="named-paragraph-container code-font"><a href="5-inf.html#SP8_2_3" class="named-paragraph-link"><span class="named-paragraph">Later generalisations beat earlier ones</span><span class="named-paragraph-number">8.2.3</span></a></span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><a href="5-inf.html#SP9" class="function-link"><span class="function-syntax">Inferences::report_inference</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="string-syntax">"discarded as a harmless contradiction"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">            </span><a href="5-inf.html#SP9" class="function-link"><span class="function-syntax">Inferences::report_inference</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="string-syntax">"discarded as redundant"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-inf.html#SP8">&#167;8</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_2_1" class="paragraph-anchor"></a><b>&#167;8.2.1. </b>In general, if two inferences give different content on the same topic, then
they contradict each other if they are both positive, but not if only one of
them is:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">North</span><span class="plain-syntax"> </span><span class="identifier-syntax">of</span><span class="plain-syntax"> </span><span class="identifier-syntax">Oxford</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="identifier-syntax">Banbury</span><span class="plain-syntax">. </span><span class="identifier-syntax">North</span><span class="plain-syntax"> </span><span class="identifier-syntax">of</span><span class="plain-syntax"> </span><span class="identifier-syntax">Oxford</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="identifier-syntax">Abingdon</span><span class="plain-syntax">.      </span><span class="identifier-syntax">CONTRADICTION</span><span class="plain-syntax">!</span>
<span class="identifier-syntax">East</span><span class="plain-syntax"> </span><span class="identifier-syntax">of</span><span class="plain-syntax"> </span><span class="identifier-syntax">Oxford</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="identifier-syntax">Cowley</span><span class="plain-syntax">. </span><span class="identifier-syntax">East</span><span class="plain-syntax"> </span><span class="identifier-syntax">of</span><span class="plain-syntax"> </span><span class="identifier-syntax">Oxford</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="identifier-syntax">not</span><span class="plain-syntax"> </span><span class="identifier-syntax">Kidlington</span><span class="plain-syntax">.   </span><span class="identifier-syntax">NO</span><span class="plain-syntax"> </span><span class="identifier-syntax">CONTRADICTION</span><span class="plain-syntax">!</span>
</pre>
<p class="commentary">But there is a subtlety when both inferences are negative: it comes down to
whether one value being false forces any alternative to be true, i.e., to
whether the details are Boolean. Consider:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">The</span><span class="plain-syntax"> </span><span class="identifier-syntax">box</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="identifier-syntax">not</span><span class="plain-syntax"> </span><span class="identifier-syntax">open</span><span class="plain-syntax">. </span><span class="identifier-syntax">The</span><span class="plain-syntax"> </span><span class="identifier-syntax">box</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="identifier-syntax">not</span><span class="plain-syntax"> </span><span class="identifier-syntax">closed</span><span class="plain-syntax">.                   </span><span class="identifier-syntax">CONTRADICTION</span><span class="plain-syntax">!</span>
<span class="identifier-syntax">The</span><span class="plain-syntax"> </span><span class="identifier-syntax">bag</span><span class="plain-syntax"> </span><span class="identifier-syntax">can</span><span class="plain-syntax"> </span><span class="identifier-syntax">be</span><span class="plain-syntax"> </span><span class="identifier-syntax">red</span><span class="plain-syntax">, </span><span class="identifier-syntax">blue</span><span class="plain-syntax"> </span><span class="identifier-syntax">or</span><span class="plain-syntax"> </span><span class="identifier-syntax">green</span><span class="plain-syntax">.</span>
<span class="identifier-syntax">The</span><span class="plain-syntax"> </span><span class="identifier-syntax">bag</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="identifier-syntax">not</span><span class="plain-syntax"> </span><span class="identifier-syntax">green</span><span class="plain-syntax">. </span><span class="identifier-syntax">The</span><span class="plain-syntax"> </span><span class="identifier-syntax">bag</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="identifier-syntax">not</span><span class="plain-syntax"> </span><span class="identifier-syntax">blue</span><span class="plain-syntax">.                    </span><span class="identifier-syntax">NO</span><span class="plain-syntax"> </span><span class="identifier-syntax">CONTRADICTION</span><span class="plain-syntax">!</span>
</pre>
<p class="commentary">In practice, Inform steers authors away from making negative assertions, so
this last subtlety doesn't arise in that form, but it does matter for inferences
drawn in world-modelling. For example, a single object O may have three
different inferences saying that it is not part of X, Y or Z respectively;
these are not mutually contradictory.<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>
</p>

<ul class="footnotetexts"><li class="footnote" id="fn:1"><p class="inwebfootnote"><sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> They differ in content but do not differ in Boolean content, because the
choice of what to be part of has more than two possible outcomes.
<a href="#fnref:1" title="return to text"> &#x21A9;</a></p></li></ul>
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Determine whether or not they contradict each other</span><span class="named-paragraph-number">8.2.1</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">existing</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">certainty</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">inf</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">certainty</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">contradiction_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">level_of_disagreement</span><span class="plain-syntax"> == </span><span class="constant-syntax">CI_DIFFER_IN_CONTENT</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax">            (</span><span class="identifier-syntax">level_of_disagreement</span><span class="plain-syntax"> == </span><span class="constant-syntax">CI_DIFFER_IN_BOOLEAN_CONTENT</span><span class="plain-syntax">))</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">contradiction_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">existing</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">certainty</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">inf</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">certainty</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">contradiction_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">level_of_disagreement</span><span class="plain-syntax"> == </span><span class="constant-syntax">CI_DIFFER_IN_CONTENT</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax">            (</span><span class="identifier-syntax">level_of_disagreement</span><span class="plain-syntax"> == </span><span class="constant-syntax">CI_DIFFER_IN_BOOLEAN_CONTENT</span><span class="plain-syntax">))</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">contradiction_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">existing</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">certainty</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">inf</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">certainty</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">contradiction_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">level_of_disagreement</span><span class="plain-syntax"> == </span><span class="constant-syntax">CI_DIFFER_IN_CONTENT</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax">            (</span><span class="identifier-syntax">level_of_disagreement</span><span class="plain-syntax"> == </span><span class="constant-syntax">CI_DIFFER_IN_BOOLEAN_CONTENT</span><span class="plain-syntax">))</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">contradiction_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">existing</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">certainty</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">inf</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">certainty</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">contradiction_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">level_of_disagreement</span><span class="plain-syntax"> == </span><span class="constant-syntax">CI_DIFFER_IN_BOOLEAN_CONTENT</span><span class="plain-syntax">)</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">contradiction_flag</span><span class="plain-syntax"> = </span><span class="identifier-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-inf.html#SP8_2">&#167;8.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_2_2" class="paragraph-anchor"></a><b>&#167;8.2.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Contradictions of certainty are forbidden, so issue a problem</span><span class="named-paragraph-number">8.2.2</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><a href="5-inf.html#SP9" class="function-link"><span class="function-syntax">Inferences::report_inference</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="string-syntax">"contradiction"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="5-inf.html#SP9" class="function-link"><span class="function-syntax">Inferences::report_inference</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">existing</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="string-syntax">"with"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="5-inf.html#SP13" class="function-link"><span class="function-syntax">Inferences::explain_contradiction</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">existing</span><span class="plain-syntax">, </span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">level_of_disagreement</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">))</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">StandardProblems::two_sentences_problem</span><span class="plain-syntax">(</span><span class="identifier-syntax">_p_</span><span class="plain-syntax">(</span><span class="identifier-syntax">PM_Contradiction</span><span class="plain-syntax">),</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">existing</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">inferred_from</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="string-syntax">"this looks like a contradiction"</span><span class="plain-syntax">,</span>
<span class="plain-syntax">        </span><span class="string-syntax">"which might be because I have misunderstood what was meant to be the subject "</span>
<span class="plain-syntax">        </span><span class="string-syntax">"of one or both of those sentences."</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-inf.html#SP8_2">&#167;8.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP8_2_3" class="paragraph-anchor"></a><b>&#167;8.2.3. </b>When talking about kinds or kinds of value, we allow new merely likely
information to displace old; but not when talking about specific objects or
values, when the initial information stands. (This is to make it easier for
people to change the effect of extensions which create kinds and specify their
likely properties.)
</p>

<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Later generalisations beat earlier ones</span><span class="named-paragraph-number">8.2.3</span></span><span class="comment-syntax"> =</span>
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">    </span><span class="identifier-syntax">LinkedLists::set_entry</span><span class="plain-syntax">(</span><span class="identifier-syntax">insertion_point</span><span class="plain-syntax">, </span><span class="identifier-syntax">SL</span><span class="plain-syntax">, </span><span class="identifier-syntax">inf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><a href="5-inf.html#SP9" class="function-link"><span class="function-syntax">Inferences::report_inference</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="string-syntax">"replaced existing also only likely one"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">PluginCalls::inference_drawn</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
</pre>
<ul class="endnotetexts"><li>This code is used in <a href="5-inf.html#SP8_2">&#167;8.2</a>.</li></ul>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. Logging inferences.</b>We keep the debugging log file more than usually well informed about what
goes on with inferences, as there is obviously great potential for mystifying
bugs if inferences are incorrectly ignored.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Inferences::report_inference</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">Inferences::report_inference</span></span>:<br/><a href="5-inf.html#SP8_1">&#167;8.1</a>, <a href="5-inf.html#SP8_2">&#167;8.2</a>, <a href="5-inf.html#SP8_2_2">&#167;8.2.2</a>, <a href="5-inf.html#SP8_2_3">&#167;8.2.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inf</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">infs</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">char</span><span class="plain-syntax"> *</span><span class="identifier-syntax">what_happened</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOGIF</span><span class="plain-syntax">(</span><span class="identifier-syntax">INFERENCES</span><span class="plain-syntax">, </span><span class="string-syntax">":::: %s: $j - $I\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">what_happened</span><span class="plain-syntax">, </span><span class="identifier-syntax">infs</span><span class="plain-syntax">, </span><span class="identifier-syntax">inf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Inferences::log_family</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">Inferences::log_family</span></span>:<br/>Knowledge Module - <a href="1-km.html#SP2">&#167;2</a>, <a href="1-km.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">f</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;null inference family&gt;"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">f</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">log_name</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Inferences::log</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">Inferences::log</span></span>:<br/>Knowledge Module - <a href="1-km.html#SP2">&#167;2</a>, <a href="1-km.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">in</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">in</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) { </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;null-inference&gt;"</span><span class="plain-syntax">); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">    </span><a href="5-inf.html#SP9" class="function-link"><span class="function-syntax">Inferences::log_family</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">in</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"-"</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">in</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">certainty</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">IMPOSSIBLE_CE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Impossible "</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">UNLIKELY_CE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Unlikely "</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">UNKNOWN_CE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;No information&gt; "</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">LIKELY_CE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Likely "</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CERTAIN_CE:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"Certain "</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">default:</span><span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"&lt;unknown-certainty&gt;"</span><span class="plain-syntax">); </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><a href="5-inf.html#SP11" class="function-link"><span class="function-syntax">Inferences::log_family_details</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">in</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. Inference families.</b>Every inference belongs to a family, and different families have different
rules, provided by method calls.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">inference_family</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">method_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">methods</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">log_name</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">CLASS_DEFINITION</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">inference_family</span><span class="plain-syntax">;</span>

<span class="reserved-syntax">inference_family</span><span class="plain-syntax"> *</span><span class="function-syntax">Inferences::new_family</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">Inferences::new_family</span></span>:<br/>Property Inferences - <a href="5-pi.html#SP2">&#167;2</a><br/>Relation Inferences - <a href="5-ri.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="identifier-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inference_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">inference_family</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">f</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">methods</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Methods::new_set</span><span class="plain-syntax">();</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">f</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">log_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">Str::duplicate</span><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">f</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<ul class="endnotetexts"><li>The structure inference_family is accessed in 4/is and here.</li></ul>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. </b>Inference families support the following methods, all optional. First:
</p>

<pre class="definitions code-font"><span class="definition-keyword">enum</span> <span class="constant-syntax">LOG_DETAILS_INF_MTID</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">VOID_METHOD_TYPE</span><span class="plain-syntax">(</span><span class="constant-syntax">LOG_DETAILS_INF_MTID</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inf</span><span class="plain-syntax">)</span>

<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Inferences::log_family_details</span><button class="popup" onclick="togglePopup('usagePopup18')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup18">Usage of <span class="code-font"><span class="function-syntax">Inferences::log_family_details</span></span>:<br/><a href="5-inf.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inf</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">VOID_METHOD_CALL</span><span class="plain-syntax">(</span><span class="identifier-syntax">inf</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family</span><span class="plain-syntax">, </span><span class="constant-syntax">LOG_DETAILS_INF_MTID</span><span class="plain-syntax">, </span><span class="identifier-syntax">inf</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. </b>This is called when <a href="5-inf.html#SP6" class="internal">Inferences::cmp</a> is comparing two inferences which both
belong to this family. It should return one of the values described in the
documentation for that function; if it isn't provided, then the inferences will
automatically be considered as either duplicative or contradictory.
</p>

<pre class="definitions code-font"><span class="definition-keyword">enum</span> <span class="constant-syntax">COMPARE_INF_MTID</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">INT_METHOD_TYPE</span><span class="plain-syntax">(</span><span class="constant-syntax">COMPARE_INF_MTID</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inf1</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inf2</span><span class="plain-syntax">)</span>

<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Inferences::family_specific_cmp</span><button class="popup" onclick="togglePopup('usagePopup19')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup19">Usage of <span class="code-font"><span class="function-syntax">Inferences::family_specific_cmp</span></span>:<br/><a href="5-inf.html#SP6">&#167;6</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inf1</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">inf2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">INT_METHOD_CALL</span><span class="plain-syntax">(</span><span class="identifier-syntax">rv</span><span class="plain-syntax">, </span><span class="identifier-syntax">inf1</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family</span><span class="plain-syntax">, </span><span class="constant-syntax">COMPARE_INF_MTID</span><span class="plain-syntax">, </span><span class="identifier-syntax">inf1</span><span class="plain-syntax">, </span><span class="identifier-syntax">inf2</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. </b>When a contradiction arises that requires a problem message, this method is
called to give it the chance to issue a better-phrased one. If it does, it
should return <span class="extract"><span class="extract-syntax">TRUE</span></span>. If it does not exist, or returns <span class="extract"><span class="extract-syntax">FALSE</span></span>, a generic
contradiction problem is generated as usual.
</p>

<pre class="definitions code-font"><span class="definition-keyword">enum</span> <span class="constant-syntax">EXPLAIN_CONTRADICTION_INF_MTID</span>
</pre>
<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">INT_METHOD_TYPE</span><span class="plain-syntax">(</span><span class="constant-syntax">EXPLAIN_CONTRADICTION_INF_MTID</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_family</span><span class="plain-syntax"> *</span><span class="identifier-syntax">f</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">A</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">B</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">similarity</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subj</span><span class="plain-syntax">)</span>

<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Inferences::explain_contradiction</span><button class="popup" onclick="togglePopup('usagePopup20')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup20">Usage of <span class="code-font"><span class="function-syntax">Inferences::explain_contradiction</span></span>:<br/><a href="5-inf.html#SP8_2_2">&#167;8.2.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">A</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference</span><span class="plain-syntax"> *</span><span class="identifier-syntax">B</span><span class="plain-syntax">,</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">similarity</span><span class="plain-syntax">, </span><span class="reserved-syntax">inference_subject</span><span class="plain-syntax"> *</span><span class="identifier-syntax">subj</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">INT_METHOD_CALL</span><span class="plain-syntax">(</span><span class="identifier-syntax">rv</span><span class="plain-syntax">, </span><span class="identifier-syntax">A</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">family</span><span class="plain-syntax">, </span><span class="constant-syntax">EXPLAIN_CONTRADICTION_INF_MTID</span><span class="plain-syntax">, </span><span class="identifier-syntax">A</span><span class="plain-syntax">, </span><span class="identifier-syntax">B</span><span class="plain-syntax">, </span><span class="identifier-syntax">similarity</span><span class="plain-syntax">, </span><span class="identifier-syntax">subj</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">rv</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="4-cos.html">&#10094;</a></li><li class="progresschapter"><a href="P-wtmd.html">P</a></li><li class="progresschapter"><a href="1-km.html">1</a></li><li class="progresschapter"><a href="2-ins.html">2</a></li><li class="progresschapter"><a href="3-prp.html">3</a></li><li class="progresschapter"><a href="4-is.html">4</a></li><li class="progresscurrentchapter">5</li><li class="progresscurrent">inf</li><li class="progresssection"><a href="5-pi.html">pi</a></li><li class="progresssection"><a href="5-ia.html">ia</a></li><li class="progresssection"><a href="5-ri.html">ri</a></li><li class="progresssection"><a href="5-tmw.html">tmw</a></li><li class="progresssection"><a href="5-tnt.html">tnt</a></li><li class="progressnext"><a href="5-pi.html">&#10095;</a></li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

